<script setup name="search">
import { onMounted, ref, reactive, computed } from 'vue'
import { useRoute, onBeforeRouteLeave } from 'vue-router'
import { Left, Avatar, AudioFile, MusicOne, Voice, Delete, Redo, Cd, MusicList } from '@icon-park/vue-next'
import { suggest, newsong } from "@/services/search"
import { debounce } from '@/utils/util'
import { usePlayStore } from '@/stores'
import { storeToRefs } from 'pinia'

import IconPark from '@/components/common/IconPark.vue'
import SearchDetail from '@/components/Search/SearchDetail.vue'

const { searchKey } = storeToRefs(usePlayStore())
const route = useRoute()
// 热搜词
const hotSearch = ref('')
// 搜索历史
const keywordList = ref([])
// 当前搜索关键字
// const searchKey = ref('')
// 搜索框
const searchRef = ref(null)
// 搜索结果数据
const state = reactive({
  searchDialog: false,  // 搜索结果详情弹窗
  showSuggest: false,   // 搜索建议列表
  albums: [],           // 专辑
  artists: [],          // 歌手
  order: [],            // 分类
  playlists: [],        // 歌单
  songs: [],            // 单曲
  newsong: []           // 推荐单曲
})
// 传递给子组件的数据
const suggestResults = computed(() => ({
  albums: state.albums,
  artists: state.artists,
  playlists: state.playlists,
  songs: state.songs,
}))
const menuItems = [
  { icon: Avatar, title: '歌手' },
  { icon: AudioFile, title: '曲风' },
  { icon: MusicOne, title: '专区' },
  { icon: Voice, title: '识曲' }
]

onMounted(() => {
  hotSearch.value = route.query.keyword
  keywordList.value = JSON.parse(localStorage.getItem('searchList')) || []
  getNewSong()
})

// 搜索
const handleSearch = event => {
  if (searchKey.value) {
    // 将搜索历史追加至头部
    keywordList.value.unshift(event)
    // 去重
    keywordList.value = [...new Set(keywordList.value)]
    // 固定数组长度
    if (keywordList.value.length > 4) keywordList.value.pop()
    // 存本地
    localStorage.setItem('searchList', JSON.stringify(keywordList.value))
    // 清空热搜词
    hotSearch.value = ''
    // 显示搜索详情弹窗
    state.searchDialog = true
    searchKey.value = event
  }
}

// 搜索按钮图标点击事件
const handleSearchClick = () => {
  // 如果有热搜词和没当前搜索框没有值，则将热搜词传入搜索框绑定的值内
  if (hotSearch.value && !searchKey.value) searchKey.value = hotSearch.value
  // 如果当前搜索框绑定的值有值，则调用搜索框搜索方法
  if (searchKey.value) handleSearch(searchKey.value)
}

// 清除搜索历史
const clearHistory = () => {
  keywordList.value = []
  localStorage.removeItem('searchList')
}

// 搜索历史标签/猜你喜欢标签点击事件
const handleTagClick = event => {
  searchKey.value = event.target.innerText
  handleSearch(event.target.innerText)
}

// 关闭弹窗
const handleClose = () => {
  state.searchDialog = !state.searchDialog
  state.showSuggest = false
  searchRef.value.focus()
}

// 搜索建议列表点击事件
const handleSuggestClick = val => {
  handleSearch(val)
}

// 在输入时显示搜索建议
const onChange = debounce(async e => {
  const res = await suggest(e)
  if (res.result) {
    const { albums, order, songs, artists, playlists } = res.result
    Object.assign(state, {
      albums: albums,
      artists: artists,
      order: order,
      playlists: playlists,
      songs: songs,
      showSuggest: true
    })
  }
}, 500)

// 获取推荐歌曲（猜你喜欢）
const getNewSong = async () => {
  const { result } = await newsong()
  state.newsong = result
}

// 清除搜索建议
const handleClear = () => {
  state.albums = []
  state.artists = []
  state.order = []
  state.playlists = []
  state.songs = []
  state.showSuggest = false
}

onBeforeRouteLeave(() => {
  handleClear()
  searchKey.value = ''
})
</script>

<template>
  <div class="search">
    <van-row class="search-header" align="center" justify="center">
      <van-col span="3" class="menu">
        <IconPark :icon="Left" :size="7" :strokeWidth="3" @click="$router.back()" />
      </van-col>
      <van-col span="18">
        <van-search ref="searchRef" v-model="searchKey" shape="round" :placeholder="hotSearch" @search="handleSearch"
          @update:model-value="onChange" @clear="handleClear" />
      </van-col>
      <van-col span="3">
        <span @click="handleSearchClick">搜索</span>
      </van-col>
    </van-row>
    <div class="search-suggest" v-if="state.showSuggest">
      <van-cell-group>
        <van-cell icon="contact" v-for="item in state.artists" :key="item.id" @click="handleSuggestClick(item.name)">
          <template #title>
            {{ item.name }}
          </template>
        </van-cell>

        <van-cell v-for="item in state.albums" :key="item.id" @click="handleSuggestClick(item.name)">
          <template #title>
            {{ item.name }}
          </template>
          <template #value>
            <span>{{ item.artist.name }}</span>
          </template>
          <template #icon>
            <IconPark :icon="Cd" :strokeWidth="2" :size="5" />
          </template>
        </van-cell>

        <van-cell icon="search" v-for="item in state.playlists" :key="item.id" @click="handleSuggestClick(item.name)">
          <template #title>
            {{ item.name }}
          </template>
          <template #icon>
            <IconPark :icon="MusicList" :strokeWidth="2" :size="5" theme="filled" />
          </template>
        </van-cell>

        <van-cell icon="search" v-for="item in state.songs" :key="item.id" @click="handleSuggestClick(item.name)">
          <template #title>
            {{ item.name }}
          </template>
          <template #value>
            <span v-for="i in item.artists" :key="i.id">{{ i.name }}</span>
          </template>
        </van-cell>
      </van-cell-group>
    </div>

    <div v-else>
      <van-row class="search-nav" gutter="24" align="center" justify="center">
        <van-col v-for="item in menuItems" :key="item.icon" span="6" class="menu">
          <IconPark :icon="item.icon" :size="7" :strokeWidth="3" theme="filled" fill="#ff343f" />
          <h5>{{ item.title }}</h5>
        </van-col>
      </van-row>

      <van-row v-if="keywordList.length" class="search-history" gutter="24" align="center" justify="center">
        <van-col span="21" class="menu">
          <h4>搜索历史</h4>
        </van-col>

        <van-col span="3" class="menu" @click="clearHistory">
          <IconPark :icon="Delete" :size="5" :strokeWidth="3" />
        </van-col>
      </van-row>

      <van-row class="search-history-item" gutter="24" align="center" justify="center">
        <van-col span="22">
          <van-tag v-for="item in keywordList" :key="item" @click="handleTagClick">{{ item }}</van-tag>
        </van-col>
      </van-row>

      <van-row class="search-guess" gutter="24" align="center" justify="center">
        <van-col span="21" class="menu">
          <h4>猜你喜欢</h4>
        </van-col>

        <van-col span="3" class="menu" @click="getNewSong">
          <IconPark :icon="Redo" :size="5" :strokeWidth="3" />
        </van-col>
      </van-row>

      <van-row class="search-guess-item" gutter="24" align="center" justify="center">
        <van-col span="22">
          <van-tag v-for="item in state.newsong" :key="item.id" @click="handleTagClick">{{ item.name }}</van-tag>
        </van-col>
      </van-row>
    </div>

    <van-popup style="height: 100vh; width: 100vw;" v-model:show="state.searchDialog" position="right" :z-index="2">
      <SearchDetail :suggestResults="suggestResults" :searchKey="searchKey" @close="handleClose" />
    </van-popup>
  </div>
</template>

<style scoped lang="scss">
.search {
  line-height: 1;

  .i-icon {
    cursor: pointer;
  }

  &-header {
    .van-col--3 {
      display: flex;
      justify-content: center;
    }

    .van-search {
      background-color: var(--color-background);

      :deep(.van-search__content--round) {
        background-color: var(--color-background-soft);
      }

      :deep(.van-field__control[type=search]) {
        color: var(--reversal-text);
      }

      :deep(.van-field__control[type=search]::placeholder) {
        color: #9b9b9b;
      }
    }
  }

  &-suggest {

    .van-cell,
    .van-cell-group {
      background-color: var(--color-background);

      :deep(.van-cell__title) {
        color: var(--reversal-text);
      }
    }

    .i-icon {
      margin: 2px 2px 0 0;
    }
  }

  &-nav {
    margin-top: 20px;

    .van-col--6 {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;

      .i-icon {
        margin-bottom: 4px;
      }
    }
  }

  &-history,
  &-guess {
    margin: 16px 0 10px 0;
    line-height: 1;

    h4 {
      margin-left: 14px;
    }

    .van-col--2 {
      display: flex;
      justify-content: center;
      align-items: center;
    }

    &-item {
      .van-tag {
        margin: 6px 10px 6px 0;
        background: #96959532;
        backdrop-filter: blur(2px);
        padding: 4px 6px;
        border-radius: 10px;
        color: var(--reversal-text);
      }
    }
  }
}
</style>